package com.git.hui.yinshua.web.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.git.hui.yinshua.api.model.ReqInfoContext;
import com.git.hui.yinshua.api.model.ResVo;
import com.git.hui.yinshua.api.model.Status;
import com.git.hui.yinshua.api.model.permission.Permission;
import com.git.hui.yinshua.api.model.permission.UserAccessRole;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.AsyncHandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 注入全局的配置信息：
 * - thymleaf 站点信息，基本信息，在这里注入
 *
 * @author yihui
 * @date 2022/6/15
 */
@Slf4j
@Component
public class AuthInterceptor implements AsyncHandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Permission permission = handlerMethod.getMethod().getAnnotation(Permission.class);
            if (permission == null) {
                permission = handlerMethod.getBeanType().getAnnotation(Permission.class);
            }

            if (permission == null || permission.role() == UserAccessRole.ALL) {
                // 无权限管控
                return true;
            }

            if (ReqInfoContext.getReqInfo() == null || ReqInfoContext.getReqInfo().getUserId() == null) {
                // 返回未登录
                return noPermission(response, Status.StatusEnum.FORBID_NOTLOGIN);
            }

            String role = ReqInfoContext.getReqInfo().getUser().getRole();
            if (permission.role() == UserAccessRole.SUPER_ADMIN) {
                // 超管，要求用户的权限同样是超管
                if (!UserAccessRole.SUPER_ADMIN.name().equalsIgnoreCase(role)) {
                    // 设置为无权限
                    return noPermission(response, Status.StatusEnum.FORBID_ERROR);
                }
            } else if (permission.role() == UserAccessRole.ADMIN) {
                // 管理员权限要求时，校验登录用户身份
                if (!UserAccessRole.SUPER_ADMIN.name().equalsIgnoreCase(role)
                        && !UserAccessRole.ADMIN.name().equalsIgnoreCase(role)) {
                    return noPermission(response, Status.StatusEnum.FORBID_ERROR);
                }
            }
        }
        return true;
    }

    private boolean noPermission(HttpServletResponse response, Status.StatusEnum status) throws IOException {
        response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        response.getWriter().println(JSONObject.toJSONString(ResVo.error(status)));
        response.getWriter().flush();
        return false;
    }
}
